package com.zxd.interview.netty.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * JDK AIO 编程模型代码
 */
public class AIOServer {


    public static void main(String[] args) throws IOException {
        // 创建一个 ExecutorService，用于处理异步操作的线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
        // 创建一个 AsynchronousChannelGroup，将线程池与该 Channel 组关联
        AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(executor);

        // 创建 AsynchronousServerSocketChannel，并绑定到指定地址和端口
        final AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open(channelGroup);
        InetSocketAddress address = new InetSocketAddress("localhost", 12345);
        serverSocketChannel.bind(address);

        System.out.println("Server started on port " + address.getPort());

        // 调用 accept 方法接收客户端连接，同时传入一个 CompletionHandler 处理连接结果
        serverSocketChannel.accept(null, new CompletionHandler<>() {
            // 当连接成功时会调用 completed 方法，传入客户端的 SocketChannel 实例作为参数
            @Override
            public void completed(AsynchronousSocketChannel clientSocketChannel, Object attachment) {
                // 继续接受下一个客户端连接，并处理当前客户端的请求
                serverSocketChannel.accept(null, this);
                handleClient(clientSocketChannel);
            }

            // 当连接失败时会调用 failed 方法，传入异常信息作为参数
            @Override
            public void failed(Throwable exc, Object attachment) {
                System.out.println("Error accepting connection: " + exc.getMessage());
            }
        });

        // 在主线程中等待，防止程序退出
        while (true) {
            try {
                Thread.sleep(Long.MAX_VALUE);
            } catch (InterruptedException e) {
                break;
            }
        }
    }

    private static void handleClient(AsynchronousSocketChannel clientSocketChannel) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // 读取客户端发送的数据，同时传入一个 CompletionHandler 处理读取结果
        clientSocketChannel.read(buffer, null, new CompletionHandler<Integer, Object>() {
            // 当读取成功时会调用 completed 方法，传入读取到的字节数和附件对象（此处不需要）
            @Override
            public void completed(Integer bytesRead, Object attachment) {
                if (bytesRead > 0) {
                    // 将 Buffer 翻转，以便进行读取操作
                    buffer.flip();
                    byte[] data = new byte[bytesRead];
                    buffer.get(data, 0, bytesRead);
                    String message = new String(data);
                    System.out.println("Received message: " + message);
                    // 向客户端发送数据
                    clientSocketChannel.write(ByteBuffer.wrap(("Hello, " + message).getBytes()));
                    buffer.clear();
                    // 继续读取下一批数据，并传入当前的 CompletionHandler 以处理读取结果
                    clientSocketChannel.read(buffer, null, this);
                } else {
                    try {
                        // 当客户端关闭连接时，关闭该 SocketChannel
                        if(null != clientSocketChannel){
                            clientSocketChannel.close();
                        }
                    } catch (IOException e) {
                        System.out.println("Error closing client socket channel: " + e.getMessage());
                    }
                }
            }

            // 当读取失败时会调用 failed 方法，传入异常信息和附件对象（此处不需要）
            @Override
            public void failed(Throwable exc, Object attachment) {
                System.out.println("Error reading from client socket channel: " + exc.getMessage());
            }
        });
    }


}
